﻿using System;

namespace MLSharp.Filters
{
    /// <summary>
    /// Defines a filter that randomizes a data set.
    /// </summary>
    public class RandomizerFilter : IDataSetFilter
	{
		#region Private Fields

		/// <summary>
		/// The random number generator to use for shuffling a data set.
		/// </summary>
    	private Random mRand;

		#endregion

		#region Public Constructors

		/// <summary>
		/// Creates a randomizer with a random seed.
		/// </summary>
		public RandomizerFilter()
		{
			mRand = new Random();
		}

		/// <summary>
		/// Creates a randomizer with the specified random seed.
		/// </summary>
		/// <param name="seed"></param>
		public RandomizerFilter(int seed)
    	{
			mRand = new Random(seed);
		}

		#endregion

		#region Public Methods

		/// <summary>
        /// Randomly shuffles the specified data set.
        /// </summary>
        /// <param name="dataSet">The data set to shuffle.</param>
        /// <remarks>
        /// This filter basically steps through the entire data set and chooses
        /// a new index for each item.  This does not guarantee that each item 
        /// will end up in a new location though as it is possible for an item
        /// to be swapped multiple times and end back up at its original location.
        /// </remarks>
        public void Transform(IDataSet dataSet)
        {
            for (int i = 0; i < dataSet.Instances.Count; i++)
            {
            	int targetIndex = mRand.Next(0, dataSet.Instances.Count);

            	Instance temp = dataSet.Instances[targetIndex];

            	dataSet.Instances[targetIndex] = dataSet.Instances[i];
            	dataSet.Instances[i] = temp;
            }

        	return;
		}

		#endregion
	}
}
